//==========================================================================
// Copyright (c) 2000-2008,  Elastos, Inc.  All Rights Reserved.
//==========================================================================

/* list.h */

#ifndef __COMMON_LIST_H__
#define __COMMON_LIST_H__

#ifndef INLINE
#ifdef _MSC_VER
#define INLINE __inline
#elif defined(_GNUC)
#ifdef __cplusplus
#define INLINE inline
#else
#define INLINE inline static
#endif
#endif
#endif  //INLINE

struct list
{
    list *next;
    list *prev;
};

/* add a node after the specified one */
INLINE void ListAddAfter(list *node, list *addNode)
{
    addNode->next = node->next;
    addNode->prev = node;
    node->next->prev = addNode;
    node->next = addNode;
}

/* add a node before the specified one */
INLINE void ListAddBefore(list *node, list *addNode)
{
    addNode->next = node;
    addNode->prev = node->prev;
    node->prev->next = addNode;
    node->prev = addNode;
}

/* Remove an node from list */
INLINE void ListRemove(list *node)
{
    node->next->prev = node->prev;
    node->prev->next = node->next;
}

INLINE list *NextNode(list *list)
{
    return list->next;
}

INLINE list *PrevNode(list *list)
{
    return list->prev;
}

/* get the first node */
INLINE list *ListGetHead(list *list)
{
    return NextNode( list );
}

/* get the last node */
INLINE list *ListGetTail(list *list)
{
    return PrevNode( list );
}

/* get the first node */
INLINE void ListAddHead(list *List, list *node)
{
    ListAddAfter( List, node );
}

/* get the last node */
INLINE void ListAddTail(list *List, list *node)
{
    ListAddHead( List, node );
}

/* check if a list is empty */
INLINE int ListEmpty(list *list)
{
    return list->next == list;
}

/* initialize a list */
INLINE void ListInit(list *list)
{
    list->next = list->prev = list;
}

/* get pointer to object containing list node */
#define GET_LIST_OBJ(node, type, field) \
    ((type *)((char *)(node) - ((unsigned int)&(((type *)1)->field) - 1)))

#endif /* __COMMON_LIST_H__ */
